<template>
  <div class="picture-upload">
    <el-upload
      ref="uploadRef"
      action="#"
      drag
      :show-file-list="false"
      list-type="picture-card"
      :limit="props.limit"
      :on-exceed="handleExceed"
      :before-upload="beforeUpload"
      :http-request="customRequest"
    >
      <div v-if="props.pictureList.length > 0">
        <el-space wrap>
          <el-image v-for="item in props.pictureList" :key="item" :src="item" class="picture-item" fit="cover" />
        </el-space>
      </div>
      <div v-else>
        <el-icon v-if="loading" :size="40"><Loading /></el-icon>
        <el-icon v-else class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">上传</div>
      </div>
    </el-upload>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import { genFileId } from "element-plus"
import { UploadFilled, Loading } from "@element-plus/icons-vue"
import { showErrorToast, showSuccessToast } from "@/utils/toast"
import type { UploadProps, UploadRawFile, UploadRequestOptions, UploadInstance } from "element-plus"

interface Props {
  pictureList: string[]
  limit?: number
}

const props = withDefaults(defineProps<Props>(), {
  limit: 1
})

const emit = defineEmits<{
  onSuccess: [value: string]
}>()

const uploadRef = ref<UploadInstance>()
const loading = ref(false)

/**
 * 覆盖前一个文件
 *
 * @param files 上传的文件
 */
const handleExceed: UploadProps["onExceed"] = (files) => {
  uploadRef.value!.clearFiles()
  const file = files[0] as UploadRawFile
  file.uid = genFileId()
  uploadRef.value!.handleStart(file)
}

/**
 * 上传前的校验
 *
 * @param file 上传的文件
 */
const beforeUpload: UploadProps["beforeUpload"] = (file) => {
  const isImage = /^image\/(jpg|png|svg|jpeg)$/.test(file.type)
  if (!isImage) {
    showErrorToast("只能上传 jpg/jpeg/png/svg 格式!")
    return false
  }
  return true
}

/**
 * 自定义上传
 *
 * @param options 上传请求配置
 */
const customRequest = async (options: UploadRequestOptions) => {
  loading.value = true
  const { file } = options
  const formData = new FormData()
  formData.append("file", file)
  loading.value = false
  showSuccessToast("上传成功")
  emit("onSuccess", "https://inews.gtimg.com/om_bt/OZpyaQVhw8QTKGp54YOp2w2oGMMi1SCrWFcPsaSZtrr6kAA/641")
}
</script>

<style lang="scss" scoped>
.picture-upload {
  width: 100%;
  height: 100%;

  :deep(.el-upload) {
    width: 100%;
    height: 100%;

    .picture-item {
      width: 80px;
      height: 80px;
      border-radius: 8px;
    }
  }
}
</style>
